//! 查询执行引擎测试套件
//! 
//! 验证火山模型执行器的正确性和性能
//! 按照notepad中的严格要求：测试驱动开发，90%覆盖率

use cdb::storage::{StorageEngine, TableSchema, Column, DataType};
use cdb::sql::{Value, QueryEngine, QueryResult};
use cdb::{Result, Error};
use std::sync::Arc;

/// 创建测试用的存储引擎
fn create_test_storage_engine() -> StorageEngine {
    let config = cdb::utils::config::Config::default();
    StorageEngine::new(&config).unwrap()
}

/// 创建测试表模式
fn create_test_table_schema() -> TableSchema {
    TableSchema {
        columns: vec![
            Column {
                name: "id".to_string(),
                data_type: DataType::Integer,
                nullable: false,
                default_value: None,
            },
            Column {
                name: "name".to_string(),
                data_type: DataType::Text(Some(100)),
                nullable: false,
                default_value: None,
            },
            Column {
                name: "age".to_string(),
                data_type: DataType::Integer,
                nullable: true,
                default_value: None,
            },
            Column {
                name: "salary".to_string(),
                data_type: DataType::Real,
                nullable: true,
                default_value: None,
            },
        ],
    }
}

/// 插入测试数据
fn insert_test_data(storage_engine: &mut StorageEngine) -> Result<()> {
    let schema = create_test_table_schema();
    storage_engine.create_table("employees".to_string(), schema)?;
    
    // 插入测试数据
    let test_data = vec![
        vec![Value::Integer(1), Value::Text("Alice".to_string()), Value::Integer(25), Value::Real(50000.0)],
        vec![Value::Integer(2), Value::Text("Bob".to_string()), Value::Integer(30), Value::Real(60000.0)],
        vec![Value::Integer(3), Value::Text("Charlie".to_string()), Value::Integer(35), Value::Real(70000.0)],
        vec![Value::Integer(4), Value::Text("Diana".to_string()), Value::Integer(28), Value::Real(55000.0)],
        vec![Value::Integer(5), Value::Text("Eve".to_string()), Value::Integer(32), Value::Real(65000.0)],
    ];
    
    for row in test_data {
        storage_engine.insert("employees", row)?;
    }
    
    Ok(())
}

#[test]
fn test_table_scan_operator() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试全表扫描
    let sql = "SELECT * FROM employees";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果
    assert_eq!(result.rows.len(), 5);
    assert_eq!(result.columns.len(), 4);
    
    // 验证第一行数据
    assert_eq!(result.rows[0][0], Value::Integer(1));
    assert_eq!(result.rows[0][1], Value::Text("Alice".to_string()));
    
    println!("✅ TableScan算子测试通过：扫描了 {} 行数据", result.rows.len());
}

#[test]
fn test_projection_operator() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试投影操作
    let sql = "SELECT name, age FROM employees";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果
    assert_eq!(result.rows.len(), 5);
    assert_eq!(result.columns.len(), 2);
    assert_eq!(result.columns[0], "name");
    assert_eq!(result.columns[1], "age");
    
    // 验证投影数据
    assert_eq!(result.rows[0][0], Value::Text("Alice".to_string()));
    assert_eq!(result.rows[0][1], Value::Integer(25));
    
    println!("✅ Projection算子测试通过：投影了 {} 列", result.columns.len());
}

#[test]
fn test_filter_operator() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试过滤操作
    let sql = "SELECT * FROM employees WHERE age > 30";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果：应该有2行数据（Charlie和Eve）
    assert_eq!(result.rows.len(), 2);
    
    // 验证过滤条件
    for row in &result.rows {
        if let Value::Integer(age) = &row[2] {
            assert!(*age > 30);
        }
    }
    
    println!("✅ Filter算子测试通过：过滤后剩余 {} 行", result.rows.len());
}

#[test]
fn test_aggregation_count() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试COUNT聚合
    let sql = "SELECT COUNT(*) FROM employees";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果
    assert_eq!(result.rows.len(), 1);
    assert_eq!(result.rows[0][0], Value::Integer(5));
    
    println!("✅ COUNT聚合算子测试通过：总计 {} 行", 5);
}

#[test]
fn test_aggregation_sum() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试SUM聚合
    let sql = "SELECT SUM(salary) FROM employees";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果：50000 + 60000 + 70000 + 55000 + 65000 = 300000
    assert_eq!(result.rows.len(), 1);
    assert_eq!(result.rows[0][0], Value::Real(300000.0));
    
    println!("✅ SUM聚合算子测试通过：总薪资 {}", 300000.0);
}

#[test]
fn test_aggregation_avg() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试AVG聚合
    let sql = "SELECT AVG(age) FROM employees";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果：(25 + 30 + 35 + 28 + 32) / 5 = 30
    assert_eq!(result.rows.len(), 1);
    assert_eq!(result.rows[0][0], Value::Real(30.0));
    
    println!("✅ AVG聚合算子测试通过：平均年龄 {}", 30.0);
}

#[test]
fn test_group_by_aggregation() {
    let mut storage_engine = create_test_storage_engine();
    
    // 创建部门表
    let dept_schema = TableSchema {
        columns: vec![
            Column {
                name: "emp_id".to_string(),
                data_type: DataType::Integer,
                nullable: false,
                default_value: None,
            },
            Column {
                name: "department".to_string(),
                data_type: DataType::Text(Some(50)),
                nullable: false,
                default_value: None,
            },
            Column {
                name: "salary".to_string(),
                data_type: DataType::Real,
                nullable: false,
                default_value: None,
            },
        ],
    };
    
    storage_engine.create_table("dept_salaries".to_string(), dept_schema).unwrap();
    
    // 插入部门数据
    let dept_data = vec![
        vec![Value::Integer(1), Value::Text("Engineering".to_string()), Value::Real(80000.0)],
        vec![Value::Integer(2), Value::Text("Engineering".to_string()), Value::Real(90000.0)],
        vec![Value::Integer(3), Value::Text("Sales".to_string()), Value::Real(60000.0)],
        vec![Value::Integer(4), Value::Text("Sales".to_string()), Value::Real(65000.0)],
        vec![Value::Integer(5), Value::Text("HR".to_string()), Value::Real(55000.0)],
    ];
    
    for row in dept_data {
        storage_engine.insert("dept_salaries", row).unwrap();
    }
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试GROUP BY聚合
    let sql = "SELECT department, COUNT(*), AVG(salary) FROM dept_salaries GROUP BY department";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果：应该有3个部门
    assert_eq!(result.rows.len(), 3);
    assert_eq!(result.columns.len(), 3);
    
    println!("✅ GROUP BY聚合算子测试通过：分组数量 {}", result.rows.len());
}

#[test]
fn test_sort_operator() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试排序操作
    let sql = "SELECT * FROM employees ORDER BY age DESC";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证排序结果：年龄应该是降序
    assert_eq!(result.rows.len(), 5);
    
    let ages: Vec<i64> = result.rows.iter()
        .map(|row| if let Value::Integer(age) = &row[2] { *age } else { 0 })
        .collect();
    
    // 验证降序排列
    for i in 1..ages.len() {
        assert!(ages[i-1] >= ages[i]);
    }
    
    println!("✅ Sort算子测试通过：按年龄降序排列");
}

#[test]
fn test_limit_operator() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试LIMIT操作
    let sql = "SELECT * FROM employees LIMIT 3";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果：应该只有3行
    assert_eq!(result.rows.len(), 3);
    
    println!("✅ Limit算子测试通过：限制返回 {} 行", result.rows.len());
}

#[test]
fn test_hash_join_operator() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    // 创建部门表
    let dept_schema = TableSchema {
        columns: vec![
            Column {
                name: "dept_id".to_string(),
                data_type: DataType::Integer,
                nullable: false,
                default_value: None,
            },
            Column {
                name: "dept_name".to_string(),
                data_type: DataType::Text(Some(50)),
                nullable: false,
                default_value: None,
            },
        ],
    };
    
    storage_engine.create_table("departments".to_string(), dept_schema).unwrap();
    
    // 插入部门数据
    let dept_data = vec![
        vec![Value::Integer(1), Value::Text("Engineering".to_string())],
        vec![Value::Integer(2), Value::Text("Sales".to_string())],
        vec![Value::Integer(3), Value::Text("HR".to_string())],
    ];
    
    for row in dept_data {
        storage_engine.insert("departments", row).unwrap();
    }
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试JOIN操作（简化版本，假设员工ID对应部门ID）
    let sql = "SELECT e.name, d.dept_name FROM employees e JOIN departments d ON e.id = d.dept_id";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果：应该有匹配的记录
    assert!(result.rows.len() > 0);
    assert_eq!(result.columns.len(), 2);
    
    println!("✅ HashJoin算子测试通过：连接结果 {} 行", result.rows.len());
}

#[test]
fn test_complex_query_execution() {
    let mut storage_engine = create_test_storage_engine();
    insert_test_data(&mut storage_engine).unwrap();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试复杂查询：过滤 + 投影 + 排序 + 限制
    let sql = "SELECT name, age FROM employees WHERE salary > 55000 ORDER BY age DESC LIMIT 2";
    let result = query_engine.execute(sql).unwrap();
    
    // 验证结果
    assert_eq!(result.rows.len(), 2);
    assert_eq!(result.columns.len(), 2);
    
    // 验证排序和过滤
    let ages: Vec<i64> = result.rows.iter()
        .map(|row| if let Value::Integer(age) = &row[1] { *age } else { 0 })
        .collect();
    
    // 应该是降序
    assert!(ages[0] >= ages[1]);
    
    println!("✅ 复杂查询执行测试通过：多算子组合执行");
}

#[test]
fn test_execution_performance() {
    let mut storage_engine = create_test_storage_engine();
    
    // 插入大量测试数据
    let schema = create_test_table_schema();
    storage_engine.create_table("large_table".to_string(), schema).unwrap();
    
    let start = std::time::Instant::now();
    
    // 插入1000行数据
    for i in 0..1000 {
        let row = vec![
            Value::Integer(i),
            Value::Text(format!("User{}", i)),
            Value::Integer(20 + (i % 50)),
            Value::Real(30000.0 + (i as f64 * 100.0)),
        ];
        storage_engine.insert("large_table", row).unwrap();
    }
    
    let insert_duration = start.elapsed();
    
    let query_engine = QueryEngine::new(Arc::new(storage_engine));
    
    // 测试查询性能
    let start = std::time::Instant::now();
    let sql = "SELECT * FROM large_table WHERE age > 40 ORDER BY salary DESC LIMIT 10";
    let result = query_engine.execute(sql).unwrap();
    let query_duration = start.elapsed();
    
    // 验证结果
    assert_eq!(result.rows.len(), 10);
    
    println!("✅ 性能测试通过：");
    println!("   插入1000行耗时: {:?}", insert_duration);
    println!("   复杂查询耗时: {:?}", query_duration);
    
    // 性能要求：查询应该在100ms内完成
    assert!(query_duration.as_millis() < 100);
}
